#pragma once
#include <glm/vec4.hpp>
#include <SDL2/SDL.h>
#include <memory>
#include <string>
#include <type_traits>

namespace gl
{
	struct context
	{
		using raw_window_type = SDL_Window;
		using raw_window_sptr = std::shared_ptr<raw_window_type>;
		using raw_context_ptr  = SDL_GLContext;
		using raw_context_deleter_type = decltype(&SDL_GL_DeleteContext);
		using raw_context_type = typename std::remove_pointer<raw_context_ptr>::type;
		using raw_context_sptr = std::shared_ptr<raw_context_type>;
		using dimension_type = int;
		using title_type = std::string;
		using title_cref = title_type const&;
		using millisecond_type = unsigned int;
		using key_type = unsigned char;


		context(dimension_type w=800, dimension_type h=600,
				title_cref title="opengl");

		void update(bool wait=false);
		void clear(glm::vec4 const& color={0, 0, 0, 1});

		millisecond_type tick() const;
		bool key(key_type k) const;
		bool key_press(key_type k);

		void ui(bool enable);
		operator bool() const { return running; }

		void fog(float start, float end) const { fog(start, end, clear_color); }
		void fog(float start, float end, glm::vec4 const& color) const;
		void fog(bool enable=false) const;

		void fov(float f);

	private:
		raw_window_sptr win;
		raw_context_sptr ctx;
		glm::vec4 clear_color;
		bool running;
		bool ui_mode;
		float fovy=0;

		void update_projection() const;
	};
}

